package controller

import (
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
	v1 "websocket/api/v1"
	"websocket/internal/consts"
	"websocket/internal/service"
	"websocket/internal/websocket"
	"websocket/utility"
)

var (
	Websocket = cWebsocket{}
)

type cWebsocket struct{}

func (c *cWebsocket) Upgrade(r *ghttp.Request) {
	conn, err := r.WebSocket()
	if err != nil {
		//glog.Error(r.Context(), err)
		g.Dump(err)
		r.Exit()
		return
	}
	uuid := utility.IdGenerator.Get()
	//do auth
	uid := r.GetHeader("uid")
	if uid != "" && gstr.IsNumeric(uid) {
		uuid = gconv.Int64(uid)
	}
	err = websocket.Manager().ClientRegister(uuid, conn)
	if err != nil {
		_ = conn.Close()
		r.Exit()
		return
	}
	loggerCtx := websocket.Context().InitLogger(websocket.ContextLogger{
		ClientTraceId: gctx.CtxId(r.Context()),
		TraceId:       gctx.CtxId(r.Context()),
		UpTime:        gtime.Now(),
		Original:      r.GetBodyString(),
	}, r.Context())
	_ = websocket.Manager().WriteMsg(loggerCtx, uuid, websocket.Manager().BuildRes(loggerCtx, &consts.WebsocketWorkRes{
		Cmd:    consts.WebsocketCmdSysConnect,
		Code:   0,
		Msg:    "ok",
		Unique: uuid,
		Data:   nil,
	}))
	return
}

func (c *cWebsocket) Clients(ctx context.Context, req *v1.WebsocketClientsReq) (res *v1.WebsocketClientsRes, err error) {
	clients := websocket.Assemble().GetClients(ctx)
	res = new(v1.WebsocketClientsRes)
	res.UniqueList = clients
	return
}

func (c *cWebsocket) BroadcastServerDatetime(ctx context.Context, req *v1.WebsocketClientsReq) (res *v1.WebsocketClientsRes, err error) {
	service.WebsocketLogic().BroadcastServerDatetime(ctx)
	return
}

func (c *cWebsocket) SetEnable(ctx context.Context, req *v1.WebsocketSetEnableReq) (res *v1.WebsocketSetEnableRes, err error) {
	websocket.Manager().SetEnable(ctx, req.Enable)
	return
}

func (c *cWebsocket) CancelAll(ctx context.Context, req *v1.WebsocketCancelAllReq) (res *v1.WebsocketCancelAllRes, err error) {
	websocket.Manager().CancelAll(ctx)
	return
}
